// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <pollux/python/vector/PyVector.h>

namespace py = pybind11;

PYBIND11_MODULE(vector, m) {
  using namespace kumo;

  py::class_<pollux::py::PyVector>(m, "Vector")
      .def("__str__", &pollux::py::PyVector::toString, py::doc(R"(
        Returns a summarized description of the Vector and its type.
      )"))
      .def("__getitem__", &pollux::py::PyVector::operator[], py::doc(R"(
        Returns a the value of an element serialized as a string.
      )"))
      .def("__len__", &pollux::py::PyVector::size, py::doc(R"(
        Number of elements in the Vector.
      )"))
      .def("__eq__", &pollux::py::PyVector::equals, py::doc(R"(
        Returns if two PyVectors have the same size and contents.
      )"))
      .def("type", &pollux::py::PyVector::type, py::doc(R"(
        Returns the Type of the Vector.
      )"))
      .def("size", &pollux::py::PyVector::size, py::doc(R"(
        Number of elements in the Vector.
      )"))
      .def("child_at", &pollux::py::PyVector::childAt, py::doc(R"(
        Returns the vector's child at position `idx`. Throws if the
        vector is not a RowVector.

        Args:
          index: The index of the child element in the RowVector.
      )"))
      .def("null_count", &pollux::py::PyVector::nullCount, py::doc(R"(
        Number of null elements in the Vector.
      )"))
      .def("is_null_at", &pollux::py::PyVector::is_null_at, py::doc(R"(
        If the Vector has a null element at `idx`.

        Args:
          index: The vector element to check.
      )"))
      .def("print_all", &pollux::py::PyVector::printAll, py::doc(R"(
        Returns a string containg all elements in the Vector.
      )"))
      .def("print_detailed", &pollux::py::PyVector::printDetailed, py::doc(R"(
        Returns a descriptive string containing details about the
        Vector and all its elements.
      )"))
      .def(
          "summarize_to_text",
          &pollux::py::PyVector::summarizeToText,
          py::doc(R"(
        Returns a human-readable summarize of the Vector.
      )"))
      .def(
          "compare",
          &pollux::py::PyVector::compare,
          py::arg("other"),
          py::arg("index"),
          py::arg("other_index"),
          py::doc(R"(
        Compares elements across Vectors.

        Args:
          index: Index on the current Vector to compare.
          other: Vector to compare to.
          other_index: Index on `other` to compare to.

        Returns:
          0 if elements are the same, non-zero otherwise.
      )"));
}
